package com.hxl.alert.utils;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.TypeUtil;

/**
 * @Title: JsonUtil
 * @Description: Json工具类，暂时内部使用fastjson实现
 * @version V1.0
 */
public class JsonUtil {
    private JsonUtil() {}

    public static String obj2json(Object obj) {
        return obj2json(obj, DateUtils.YYYY_MM_DD_HH_MM_SS);
    }

    /**
     * 
     * @Description: 
     * @param obj
     * @param beIgnoreNull 是否忽略null值
     * @param beFormat  是否格式化
     * @param dataFormat  指定日期格式化 
     * @return
     */
    public static String obj2json2(Object obj, boolean beIgnoreNull, boolean beFormat, String dataFormat) {
        List<SerializerFeature> features = new ArrayList<>();
        if (!beIgnoreNull) {
            features.add(SerializerFeature.WriteMapNullValue);
            features.add(SerializerFeature.DisableCircularReferenceDetect);
            features.add(SerializerFeature.WriteNullStringAsEmpty);
            features.add(SerializerFeature.WriteNullListAsEmpty);
            features.add(SerializerFeature.WriteDateUseDateFormat);
        }
        if (beFormat) {
            features.add(SerializerFeature.PrettyFormat);
        }
        features.add(SerializerFeature.WriteDateUseDateFormat);
        return obj2json2(obj, dataFormat, features.toArray(new SerializerFeature[] {}));
    }

    public static String obj2json2(Object obj, boolean beIgnoreNull, boolean beFormat) {
        return obj2json2(obj, beIgnoreNull, beFormat, DateUtils.YYYY_MM_DD_HH_MM_SS);
    }

    public static String obj2json2(Object obj, boolean beIgnoreNull) {
        return obj2json2(obj, beIgnoreNull, false);
    }

    public static String obj2json2(Object obj) {
        return obj2json2(obj, false);
    }

    /**
     * 
     * @Description: 对象转json
     * @param obj
     *            对象
     * @param beFormat
     *            是否格式化
     * @return json字符串
     */
    public static String obj2json(Object obj, boolean beFormat) {
        return obj2json2(obj, false, beFormat);
    }

    /**
    * 
    * @Description: 对象转json
    * @param obj
    * @param dataFormat 日期格式
    * @return
    * 
    * 如果java bean的Date类型属性需要特殊处理，使用注解
    * @com.alibaba.fastjson.annotation.JSONField
    */
    public static String obj2json(Object obj, String dataFormat) {
        return obj2json2(obj, false, false, dataFormat);
    }

    private static String obj2json2(Object obj, String dataFormat, SerializerFeature... feature) {
        String defaultFormat = JSONObject.DEFFAULT_DATE_FORMAT;
        JSONObject.DEFFAULT_DATE_FORMAT = dataFormat;
        String json = JSON.toJSONString(obj, feature);
        JSONObject.DEFFAULT_DATE_FORMAT = defaultFormat;
        return json;
    }

    /**
     * 
     * @Description: xml转json
     * @param xml
     * @return json字符串
     */
    public static String xml2json(String xml) {
        return cn.hutool.json.JSONUtil.xmlToJson(xml).toJSONString(0);
    }

    /**
     * 
     * @Description: json转对象
     * @param jsonString
     * @param beanClass
     * @return 实体类对象
     */
    public static <T> T json2Obj(String jsonString, Class<T> beanClass) {
        return JSON.parseObject(jsonString, beanClass);
    }

    /**
     * 
     * @Description JSON字符串转为实体类对象，转换异常将被抛出
     *
     * @param <T>
     *            Bean类型
     * @param jsonString
     *            JSON字符串
     * @param typeReference
     *            {@link TypeReference}类型参考子类，可以获取其泛型参数中的Type类型
     * @param ignoreError
     *            是否忽略错误
     * @return 实体类对象
     */
    public static <T> T json2Obj(String jsonString, TypeReference<T> typeReference,
        boolean ignoreError) {
        /* return cn.hutool.json.JSONUtil.toBean(jsonString, TypeUtil.getTypeArgument(typeReference.getClass()),
            ignoreError);*/
        return json2Obj(jsonString, typeReference);
    }

    /**
     * 
     * @Description: 
     * @param <T>
     * @param jsonString
     * @param typeReference
     * @return
     * 
     * eg: JsonUtil.json2Obj(jsonString, new com.sf.nwms.core.util.lang.TypeReference<List<JavaBean>())
     */
    public static <T> T json2Obj(String jsonString, TypeReference<T> typeReference) {
        return JSON.parseObject(jsonString, TypeUtil.getTypeArgument(typeReference.getClass()));
    }

    /**
     * 
     * @Description: json转对象
     * @param jsonString
     *            json字符串
     * @param beanType
     *            实体类对象类型
     * @param ignoreError
     *            是否忽略错误
     * @return 实体类对象
     */
    public static <T> T json2Obj(String jsonString, Type beanType, boolean ignoreError) {
        return JSON.parseObject(jsonString, beanType);
    }

}
